import os
import logging
from logging.handlers import RotatingFileHandler
from datetime import datetime
import traceback
from typing import Optional, Any

# 日志级别映射
LOG_LEVELS = {
    'DEBUG': logging.DEBUG,
    'INFO': logging.INFO,
    'WARNING': logging.WARNING,
    'ERROR': logging.ERROR,
    'CRITICAL': logging.CRITICAL
}


class CustomLogger:
    """自定义日志系统，支持文件和控制台输出，以及日志轮转"""

    def __init__(self,
                 name: str = 'DouyinBot',
                 log_dir: str = 'logs',
                 log_level: str = 'INFO',
                 max_file_size: int = 10 * 1024 * 1024,  # 10MB
                 backup_count: int = 5):
        """
        初始化日志系统

        Args:
            name: 日志器名称
            log_dir: 日志存储目录
            log_level: 日志级别
            max_file_size: 单个日志文件最大大小
            backup_count: 保留的备份日志文件数量
        """
        self.name = name
        self.log_dir = log_dir
        self.log_level = LOG_LEVELS.get(log_level.upper(), logging.INFO)
        self.max_file_size = max_file_size
        self.backup_count = backup_count

        # 确保日志目录存在
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)

        # 初始化日志器
        self.logger = logging.getLogger(name)
        self.logger.setLevel(self.log_level)

        # 格式化器
        self.formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S'
        )

        # 添加文件处理器
        self._add_file_handler()

        # 添加控制台处理器
        self._add_console_handler()

    def _add_file_handler(self):
        """添加文件日志处理器"""
        log_file = os.path.join(self.log_dir, f'{self.name}_{datetime.now().strftime("%Y%m%d")}.log')
        file_handler = RotatingFileHandler(
            log_file,
            maxBytes=self.max_file_size,
            backupCount=self.backup_count
        )
        file_handler.setLevel(self.log_level)
        file_handler.setFormatter(self.formatter)
        self.logger.addHandler(file_handler)

    def _add_console_handler(self):
        """添加控制台日志处理器"""
        console_handler = logging.StreamHandler()
        console_handler.setLevel(self.log_level)
        console_handler.setFormatter(self.formatter)
        self.logger.addHandler(console_handler)

    def debug(self, message: str, *args: Any, **kwargs: Any) -> None:
        """记录DEBUG级别的日志"""
        self.logger.debug(message, *args, **kwargs)

    def info(self, message: str, *args: Any, **kwargs: Any) -> None:
        """记录INFO级别的日志"""
        self.logger.info(message, *args, **kwargs)

    def warning(self, message: str, *args: Any, **kwargs: Any) -> None:
        """记录WARNING级别的日志"""
        self.logger.warning(message, *args, **kwargs)

    def error(self, message: str, *args: Any, **kwargs: Any) -> None:
        """记录ERROR级别的日志"""
        self.logger.error(message, *args, **kwargs)

    def critical(self, message: str, *args: Any, **kwargs: Any) -> None:
        """记录CRITICAL级别的日志"""
        self.logger.critical(message, *args, **kwargs)

    def exception(self, message: str, *args: Any) -> None:
        """记录异常信息，自动添加堆栈跟踪"""
        self.logger.error(message, *args, exc_info=True)

    def log_traceback(self, message: str = "异常堆栈跟踪") -> None:
        """记录完整的堆栈跟踪信息"""
        tb = traceback.format_exc()
        self.logger.error(f"{message}\n{tb}")


# 单例模式获取日志实例
def get_logger(name: Optional[str] = None,
               log_dir: str = 'logs',
               log_level: str = 'INFO') -> CustomLogger:
    """获取日志实例（单例模式）"""
    if not hasattr(get_logger, 'instance'):
        logger_name = name if name else 'DouyinBot'
        get_logger.instance = CustomLogger(
            name=logger_name,
            log_dir=log_dir,
            log_level=log_level
        )
    return get_logger.instance
